﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace SharingCenter.Web.Classes.Events
{
    using SharingCenter.Web.Classes;
    using System.Web.UI.WebControls;
    using SharingCenter.Web.Classes.enums;
    using System.Data.Linq;
    using System.Xml.Linq;
    using SharingCenter.Web.Classes.Messages;
    using SharingCenter.Web.Classes.SiteEvents;
    using SharingCenter.Web.Classes.Requests;

    public enum EventStatus
    {
        NotStarted = 1,
        InProgress,
        Ended,
        NA
    }

    public class EventOperations
    {

        public static bool IsUserParticipant(Guid eventId, Guid userId)
        {
            using (scDataContext cxt = new scDataContext())
            {
                var q = from t in cxt.Sc_EventParticipants
                        where t.EventId == eventId && t.UserId == userId
                        select t;
                return q.Count() > 0;
            }
        }

        public static void AddSiteEventOnApproval(Guid userId, Guid eventId, string eventName)
        {

        }

        public static List<Sc_Event> GetFavoriteEventsByUserId(Guid userId)
        {
            using (scDataContext cxt = new scDataContext())
            {
                var q = from f in cxt.Sc_SharedFavorites
                        join t in cxt.Sc_Events
                        on f.ContextId equals t.EventId
                        where f.UserId == userId
                        orderby t.StartDate
                        select t;
                return q.ToList();
            }
        }

        public static void AddParticipantToEvent(Guid eventId, Guid userId, string comment, bool submitChange)
        {
            if (!IsUserParticipant(eventId, userId))
            {

                Sc_EventParticipant p = new Sc_EventParticipant();
                p.SeqId = Guid.NewGuid();
                p.EventId = eventId;
                p.UserId = userId;
                p.StatusChangeDate = DateTime.Now;
                p.Comment = comment;

                using (scDataContext cxt = new scDataContext())
                {
                    cxt.Sc_EventParticipants.InsertOnSubmit(p);

                    Sc_Event evt = EventOperations.GetEventFromEvnetId(eventId);
                    if (evt.CreatorUserId != userId && evt.EventSource == EntityType.UserEvent)
                    {
                        EventOperations.SendEventApproveMessage(evt.EventId, evt.Title, userId);
                        SendSiteEvent(eventId, evt.Title, userId);
                    }

                    if (submitChange)
                    {
                        try
                        {
                           cxt.SubmitChanges(ConflictMode.FailOnFirstConflict);

                        }
                        catch { }
                    }
                }
            }
        }

        public static void AddParticipantToEvent(Guid eventId, Guid userId, string comment, scDataContext cxt, bool submitChange)
        {
            if (!IsUserParticipant(eventId, userId))
            {

                Sc_EventParticipant p = new Sc_EventParticipant();
                p.SeqId = Guid.NewGuid();
                p.EventId = eventId;
                p.UserId = userId;
                p.StatusChangeDate = DateTime.Now;
                p.Comment = comment;

                cxt.Sc_EventParticipants.InsertOnSubmit(p);

                /*
                Sc_Event evt = EventOperations.GetEventFromEvnetId(eventId);
                if (evt.CreatorUserId != userId && evt.EventSource == EntityType.UserEvent)
                {
                    EventOperations.SendEventApproveMessage(evt.EventId, evt.Title, userId);
                    SendSiteEvent(eventId, evt.Title, userId);
                }

                if (submitChange)
                {
                    try
                    {
                        cxt.SubmitChanges(ConflictMode.FailOnFirstConflict);

                    }
                    catch { }
                }*/

                if (submitChange)
                {
                    cxt.SubmitChanges();
                }
            }
        }

        public static void AddParticipantsToEvent(Guid eventId, List<Guid> userIdList, string comment)
        {
            using (scDataContext cxt = new scDataContext())
            {
                foreach (Guid userId in userIdList)
                {
                    if (!IsUserParticipant(eventId, userId))
                    {

                        Sc_EventParticipant p = new Sc_EventParticipant();
                        p.SeqId = Guid.NewGuid();
                        p.EventId = eventId;
                        p.UserId = userId;
                        p.StatusChangeDate = DateTime.Now;
                        p.Comment = comment;


                        cxt.Sc_EventParticipants.InsertOnSubmit(p);

                        Sc_Event evt = EventOperations.GetEventFromEvnetId(eventId);
                        if (evt.CreatorUserId != userId && evt.EventSource == EntityType.UserEvent)
                        {
                            EventOperations.SendEventApproveMessage(evt.EventId, evt.Title, userId);
                            SendSiteEvent(eventId, evt.Title, userId);
                        }

                        
                    }
                }

                cxt.SubmitChanges(ConflictMode.FailOnFirstConflict);
            }
        }

        public static void SendSiteEvent(Guid eventId, string eventName, Guid userId)
        {
            XElement cxt = new XElement("Event",
                new XElement("EventId", eventId.ToString()),
                new XElement("UserId", userId),
                new XElement("EventName", eventName)
                );
            SiteEventOperations.AddEvent("Events", "EventRequestApproved", "Events", userId, cxt, true, null, false);
        }

        public static void SendEventApproveMessage(Guid eventId, string eventName, Guid userId)
        {
            XElement context = new XElement("Context",
                     new XAttribute("XsltFolderInMod", "Events"),
                     new XElement("Event",
                         new XAttribute("Name", "EventRequestApproved"),
                         new XElement("EventId", eventId.ToString()),
                         new XElement("EventName", eventName),
                         new XElement("UserId", userId.ToString())
                         ));

            MessageOperations.SendSystemMessage(WebProfile.Current.UserId, userId, "EventRequestApproved", context, true);
        }

        public static List<Sc_EventParticipant> GetParticipantList(Guid eventId, int count)
        {
            using (scDataContext cxt = new scDataContext())
            {
                var q = count >= 0 ?
                        (from r in cxt.Sc_EventParticipants
                         where r.EventId == eventId
                         select r).Take(count) : 
                         from r in cxt.Sc_EventParticipants
                                                 where r.EventId == eventId
                                                 select r;
                return q.ToList();
            }     
        }

        public static List<Guid> GetParticipantsByEventId(EntityType eventType, Guid eventId)
        {
            using (scDataContext cxt = new scDataContext())
            {
                var q =
                        from r in cxt.Sc_EventParticipants
                        where r.EventId == eventId
                        select r.UserId;
                return q.ToList();
            }       
        }

        public static List<Sc_Event> GetEventsByCreatorUserId(Guid userId)
        {
            using (scDataContext cxt = new scDataContext())
            {
                var q = from t in cxt.Sc_Events
                        where t.CreatorUserId == userId
                        select t;
                return q.ToList();
            }
        }

        public static List<Sc_Event> GetEventsByJoinerUserId(EntityType type, Guid userId)
        {
            using (scDataContext cxt = new scDataContext())
            {
                var q = from t in cxt.Sc_Events
                        from r in cxt.Sc_EventParticipants
                        where r.UserId == userId && t.AdminApproved
                        select t;
                return q.ToList();
            }
        }

        public static Sc_Event GetEventFromEvnetId(Guid eventId)
        {
            
            try
            {
                using (scDataContext cxt = new scDataContext())
                {
                    cxt.ObjectTrackingEnabled = false;
                    return cxt.Sc_Events.Single(d => d.EventId == eventId);
                }
            }
            catch
            {
                return null;
            }
        }

        public static void DeleteEvent(Guid eventId)
        {
            Sc_Event tmp = GetEventFromEvnetId(eventId);
            if (tmp != null)
            {
                var req = Requests.RequestOperations.GetRequestsByEntityType(EntityType.UserEvent, eventId, RequestStatus.NA, LogicalOperator.NA);
                Comments.CommentOperations.DeleteAllThreadsInContext("Event", "", eventId, false);
                scDataContext.Instance.Sc_SharedRequests.DeleteAllOnSubmit(req);
                scDataContext.Instance.Sc_Events.DeleteOnSubmit(tmp);
                scDataContext.Instance.SubmitChanges();
            }
            //
        }

        public static List<Sc_SharedRequest> GetEventPendingRequestsByEventId(Guid eventId)
        {
            return Requests.RequestOperations.GetRequestsByEntityType(EntityType.UserEvent, eventId, RequestStatus.Pending, LogicalOperator.Is);
        }

        public static List<Sc_Event> GetHotEvents(int takeCount)
        {
            using (scDataContext cxt = new scDataContext())
            {
                var q = (from t in cxt.Sc_Events
                         where t.Privacy == PrivacyEnum.Public && t.AdminApproved
                         && DateTime.Now < t.StartDate
                         orderby t.TotalParticipants descending, t.StartDate
                         select t).Take(takeCount);
                return q.ToList();
            }
        }
    }
}
